// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <turbo/utility/status.h>
#include <nebula/types/type_fwd.h>
#include <turbo/base/macros.h>

namespace nebula {

    /// \brief Abstract array visitor class
    ///
    /// Subclass this to create a visitor that can be used with the Array::Accept()
    /// method.
    class TURBO_EXPORT ArrayVisitor {
    public:
        virtual ~ArrayVisitor() = default;

        virtual turbo::Status Visit(const NullArray &array);

        virtual turbo::Status Visit(const BooleanArray &array);

        virtual turbo::Status Visit(const Int8Array &array);

        virtual turbo::Status Visit(const Int16Array &array);

        virtual turbo::Status Visit(const Int32Array &array);

        virtual turbo::Status Visit(const Int64Array &array);

        virtual turbo::Status Visit(const UInt8Array &array);

        virtual turbo::Status Visit(const UInt16Array &array);

        virtual turbo::Status Visit(const UInt32Array &array);

        virtual turbo::Status Visit(const UInt64Array &array);

        virtual turbo::Status Visit(const Fp16Array &array);

        virtual turbo::Status Visit(const Fp32Array &array);

        virtual turbo::Status Visit(const Fp64Array &array);

        virtual turbo::Status Visit(const StringArray &array);

        virtual turbo::Status Visit(const StringViewArray &array);

        virtual turbo::Status Visit(const BinaryArray &array);

        virtual turbo::Status Visit(const BinaryViewArray &array);

        virtual turbo::Status Visit(const LargeStringArray &array);

        virtual turbo::Status Visit(const LargeBinaryArray &array);

        virtual turbo::Status Visit(const FixedSizeBinaryArray &array);

        virtual turbo::Status Visit(const Date32Array &array);

        virtual turbo::Status Visit(const Date64Array &array);

        virtual turbo::Status Visit(const Time32Array &array);

        virtual turbo::Status Visit(const Time64Array &array);

        virtual turbo::Status Visit(const TimestampArray &array);

        virtual turbo::Status Visit(const DayTimeIntervalArray &array);

        virtual turbo::Status Visit(const MonthDayNanoIntervalArray &array);

        virtual turbo::Status Visit(const MonthIntervalArray &array);

        virtual turbo::Status Visit(const DurationArray &array);

        virtual turbo::Status Visit(const Decimal128Array &array);

        virtual turbo::Status Visit(const Decimal256Array &array);

        virtual turbo::Status Visit(const ListArray &array);

        virtual turbo::Status Visit(const LargeListArray &array);

        virtual turbo::Status Visit(const ListViewArray &array);

        virtual turbo::Status Visit(const LargeListViewArray &array);

        virtual turbo::Status Visit(const MapArray &array);

        virtual turbo::Status Visit(const FixedSizeListArray &array);

        virtual turbo::Status Visit(const StructArray &array);

        virtual turbo::Status Visit(const SparseUnionArray &array);

        virtual turbo::Status Visit(const DenseUnionArray &array);

        virtual turbo::Status Visit(const DictionaryArray &array);

        virtual turbo::Status Visit(const RunEndEncodedArray &array);

        virtual turbo::Status Visit(const ExtensionArray &array);
    };

    /// \brief Abstract type visitor class
    ///
    /// Subclass this to create a visitor that can be used with the DataType::Accept()
    /// method.
    class TURBO_EXPORT TypeVisitor {
    public:
        virtual ~TypeVisitor() = default;

        virtual turbo::Status Visit(const NullType &type);

        virtual turbo::Status Visit(const BooleanType &type);

        virtual turbo::Status Visit(const Int8Type &type);

        virtual turbo::Status Visit(const Int16Type &type);

        virtual turbo::Status Visit(const Int32Type &type);

        virtual turbo::Status Visit(const Int64Type &type);

        virtual turbo::Status Visit(const UInt8Type &type);

        virtual turbo::Status Visit(const UInt16Type &type);

        virtual turbo::Status Visit(const UInt32Type &type);

        virtual turbo::Status Visit(const UInt64Type &type);

        virtual turbo::Status Visit(const Fp16Type &type);

        virtual turbo::Status Visit(const Fp32Type &type);

        virtual turbo::Status Visit(const Fp64Type &type);

        virtual turbo::Status Visit(const StringType &type);

        virtual turbo::Status Visit(const StringViewType &type);

        virtual turbo::Status Visit(const BinaryType &type);

        virtual turbo::Status Visit(const BinaryViewType &type);

        virtual turbo::Status Visit(const LargeStringType &type);

        virtual turbo::Status Visit(const LargeBinaryType &type);

        virtual turbo::Status Visit(const FixedSizeBinaryType &type);

        virtual turbo::Status Visit(const Date64Type &type);

        virtual turbo::Status Visit(const Date32Type &type);

        virtual turbo::Status Visit(const Time32Type &type);

        virtual turbo::Status Visit(const Time64Type &type);

        virtual turbo::Status Visit(const TimestampType &type);

        virtual turbo::Status Visit(const MonthDayNanoIntervalType &type);

        virtual turbo::Status Visit(const MonthIntervalType &type);

        virtual turbo::Status Visit(const DayTimeIntervalType &type);

        virtual turbo::Status Visit(const DurationType &type);

        virtual turbo::Status Visit(const Decimal128Type &type);

        virtual turbo::Status Visit(const Decimal256Type &type);

        virtual turbo::Status Visit(const ListType &type);

        virtual turbo::Status Visit(const LargeListType &type);

        virtual turbo::Status Visit(const ListViewType &scalar);

        virtual turbo::Status Visit(const LargeListViewType &scalar);

        virtual turbo::Status Visit(const MapType &type);

        virtual turbo::Status Visit(const FixedSizeListType &type);

        virtual turbo::Status Visit(const StructType &type);

        virtual turbo::Status Visit(const SparseUnionType &type);

        virtual turbo::Status Visit(const DenseUnionType &type);

        virtual turbo::Status Visit(const DictionaryType &type);

        virtual turbo::Status Visit(const RunEndEncodedType &type);

        virtual turbo::Status Visit(const ExtensionType &type);
    };

    /// \brief Abstract scalar visitor class
    ///
    /// Subclass this to create a visitor that can be used with the Scalar::Accept()
    /// method.
    class TURBO_EXPORT ScalarVisitor {
    public:
        virtual ~ScalarVisitor() = default;

        virtual turbo::Status Visit(const NullScalar &scalar);

        virtual turbo::Status Visit(const BooleanScalar &scalar);

        virtual turbo::Status Visit(const Int8Scalar &scalar);

        virtual turbo::Status Visit(const Int16Scalar &scalar);

        virtual turbo::Status Visit(const Int32Scalar &scalar);

        virtual turbo::Status Visit(const Int64Scalar &scalar);

        virtual turbo::Status Visit(const UInt8Scalar &scalar);

        virtual turbo::Status Visit(const UInt16Scalar &scalar);

        virtual turbo::Status Visit(const UInt32Scalar &scalar);

        virtual turbo::Status Visit(const UInt64Scalar &scalar);

        virtual turbo::Status Visit(const Fp16Scalar &scalar);

        virtual turbo::Status Visit(const Fp32Scalar &scalar);

        virtual turbo::Status Visit(const Fp64Scalar &scalar);

        virtual turbo::Status Visit(const StringScalar &scalar);

        virtual turbo::Status Visit(const StringViewScalar &scalar);

        virtual turbo::Status Visit(const BinaryScalar &scalar);

        virtual turbo::Status Visit(const BinaryViewScalar &scalar);

        virtual turbo::Status Visit(const LargeStringScalar &scalar);

        virtual turbo::Status Visit(const LargeBinaryScalar &scalar);

        virtual turbo::Status Visit(const FixedSizeBinaryScalar &scalar);

        virtual turbo::Status Visit(const Date64Scalar &scalar);

        virtual turbo::Status Visit(const Date32Scalar &scalar);

        virtual turbo::Status Visit(const Time32Scalar &scalar);

        virtual turbo::Status Visit(const Time64Scalar &scalar);

        virtual turbo::Status Visit(const TimestampScalar &scalar);

        virtual turbo::Status Visit(const DayTimeIntervalScalar &scalar);

        virtual turbo::Status Visit(const MonthDayNanoIntervalScalar &type);

        virtual turbo::Status Visit(const MonthIntervalScalar &scalar);

        virtual turbo::Status Visit(const DurationScalar &scalar);

        virtual turbo::Status Visit(const Decimal128Scalar &scalar);

        virtual turbo::Status Visit(const Decimal256Scalar &scalar);

        virtual turbo::Status Visit(const ListScalar &scalar);

        virtual turbo::Status Visit(const LargeListScalar &scalar);

        virtual turbo::Status Visit(const ListViewScalar &scalar);

        virtual turbo::Status Visit(const LargeListViewScalar &scalar);

        virtual turbo::Status Visit(const MapScalar &scalar);

        virtual turbo::Status Visit(const FixedSizeListScalar &scalar);

        virtual turbo::Status Visit(const StructScalar &scalar);

        virtual turbo::Status Visit(const DictionaryScalar &scalar);

        virtual turbo::Status Visit(const SparseUnionScalar &scalar);

        virtual turbo::Status Visit(const DenseUnionScalar &scalar);

        virtual turbo::Status Visit(const RunEndEncodedScalar &scalar);

        virtual turbo::Status Visit(const ExtensionScalar &scalar);
    };

}  // namespace nebula
